package org.jumiz.framework.base.wrapper;

import org.jumiz.framework.base.reflect.*;
import org.jumiz.framework.base.support.BeanFactory;
import org.jumiz.framework.base.support.SqlBuilder;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.*;
import java.util.function.Consumer;

/**
 * 查询
 * @author jumiz
 */
public abstract class QueryWrapper<T> implements Query<T>, Wrapper, Serializable {

    private SqlDefinition sqlDefinition = new SqlDefinition();

//    private List<FieldInfo> fieldInfoList = new LinkedList<>();

    public QueryWrapper(Class<T> entityClass) {
        this.sqlDefinition.setEntityClass(entityClass);
        this.sqlDefinition.setTableName(
                this.getTableName()
        );
        this.sqlDefinition.setOperateType(OperateType.SELECT);
        this.sqlDefinition.setColumnDefinition(this.columnDefinition());
    }

    public QueryWrapper<T> eq(SFunction<T, String> column, Object value) {
        return this;
    };

//    public QueryWrapper<T> eq(SFunction<T, String> column, Object value) {
//        try {
//            Method method = column.getClass().getDeclaredMethod("writeReplace");
//            method.setAccessible(true);
//            SerializedLambda lambda = (SerializedLambda)method.invoke(column);
//            // 方法名称
//            String methodName = lambda.getImplMethodName();
//            // 字段名称
//            String fieldName = PropertyNameUtil.methodToProperty(methodName);
//            // 实体对象的class
//            Class<?> aClass = Class.forName(lambda.getImplClass().replaceAll("/", "."));
//            // 调用扩展
//            fieldName = BeanFactory.getBean(FieldAnnotationSupport.class).getFieldName(aClass, fieldName, methodName);
//            fieldInfoList.add(
//                    FieldInfo.builder().name(fieldName).value(value).filedType(FiledType.STING).operateType(OperateType.AND).build()
//            );
//        } catch (Exception e) {
//            throw new ParserException("解析异常", e);
//        }
//        return this;
//    }

    public QueryWrapper<T> and(Consumer<T> consumer){
        return this;
    };

    public QueryWrapper<T> or(Consumer<T> consumer) {
        return this;
    };

    public String toSqlString() {
        return null;
    };
//    {
//        BeanDefinition beanDefinition = new BeanDefinition();
//        beanDefinition.setWhereList(fieldInfoList);
//        beanDefinition.setOperateType(OperateType.SELECT);
//        beanDefinition.setTableName(getTableName());
//        SqlBuilder.SqlResult sqlResult = BeanFactory.getBean(SqlBuilder.class).buildPrepareSql(beanDefinition);
//        return sqlResult.getSql();
//    }

    private String getTableName() {
        Class<T> entityClass = this.sqlDefinition.getEntityClass();
        String simpleName = entityClass.getSimpleName();
        String tableName = BeanFactory.getBean(SqlBuilder.class).getTableName(entityClass);
        return Optional.ofNullable(tableName).orElse(simpleName);
    }

    private ColumnDefinition columnDefinition() {
        Class<T> entityClass = this.sqlDefinition.getEntityClass();
        Field[] declaredFields = entityClass.getDeclaredFields();
        ColumnDefinition columnDefinition = ColumnDefinition.create();
        for (Field field : declaredFields) {
            field.setAccessible(true);
            String fieldName = field.getName();
            String columnName = BeanFactory.getBean(SqlBuilder.class).getColumnName(field);
            Class<?> type = field.getType();
            columnDefinition.put(fieldName, Optional.ofNullable(columnName).orElse(fieldName), type);
        }
        return columnDefinition;
    }

    protected SqlDefinition getSqlDefinition() {
        return sqlDefinition;
    }
}
